package org.tamal.struts;


import java.util.Map;

import org.apache.log4j.Logger;
import org.tamal.HttpSession;
import org.tamal.annotation.SkipAuthentication;
import org.tamal.persistence.User;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

/**
 * This interceptor validates every struts requests and allows authenticated
 * sessions to complete the request.
 * @author Tamal Kanti Nath
 */
public final class AuthenticationInterceptor implements Interceptor {

    private static final long serialVersionUID = 8363187392822989198L;
    private final transient Logger log = Logger.getLogger(getClass().getName());

    @Override
    public void destroy() {
        log.info("destroy");
    }

    @Override
    public void init() {
        log.info("init");
    }

    /**
     * This method checks the session for a logged in user. If found, it
     * forwards the control to the next interceptor. It always bypasses the
     * validation of login action.
     * @param invocation the action invocation
     * @return the return code, either returned from
     *     {@link ActionInvocation#invoke()}, or from the interceptor itself.
     * @throws Exception any system-level error, as defined in
     *     {@link com.opensymphony.xwork2.Action#execute()}.
     */
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        ActionContext context = invocation.getInvocationContext();
        String actionName = context.getName();
        if (StrutsUtils.isAnnotated(invocation, SkipAuthentication.class)) {
            log.info("Authentication skipped for action: " + actionName);
            return invocation.invoke();
        }
        Map<String, Object> session = context.getSession();
        User user = (User) session.get(HttpSession.USER);
        if (user == null) {
            log.info("Log in to browse action: " + actionName);
            return Action.LOGIN;
        }
        log.info(user.getName() + " is browsing " + actionName);
        return invocation.invoke();
    }

}
